package controlador;

import vista.InterfazGraficaProducto;
import vista.Mensaje;
import vista.VentanaIndependiente;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.DefaultCellEditor;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

import modelo.Buscador;
import modelo.CategoriaDao;
import modelo.Ingrediente;
import modelo.IngredienteDao;
import modelo.Producto;
import modelo.ProductoDao;
import modelo.ProductoIngrediente;
import modelo.ProductoIngredienteDao;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

public class ControladorProducto extends ControladorActualizadorBD implements ActionListener,WindowListener,KeyListener,FocusListener,PropertyChangeListener,Buscador
{

	private InterfazGraficaProducto interfazGrafica;
	private ControladorPrincipal controladorPrincipal;
	private ProductoDao productoDao;
	private CategoriaDao categoriaDao;
	private IngredienteDao ingredienteDao;
	private ArrayList<Producto> productos;
	private boolean guardando;
	private TableModel modeloTabla;
	
	public ControladorProducto(ControladorPrincipal controladorPrincipal)
	{
		
		this.controladorPrincipal= controladorPrincipal;
			
		interfazGrafica= new InterfazGraficaProducto();
		
		productoDao= new ProductoDao();
        categoriaDao= new CategoriaDao();
        ingredienteDao = new IngredienteDao();
        
        productos= new ArrayList<Producto>();
        guardando=false;
        
        modeloTabla= new DefaultTableModel();
		
		
		interfazGrafica.addListener((WindowListener) this);
		interfazGrafica.addListener((ActionListener) this);
		interfazGrafica.addListener((FocusListener) this);
		interfazGrafica.addListener((KeyListener) this);
		interfazGrafica.addListener((PropertyChangeListener) this);
		interfazGrafica.visualizarVentana();
	}
	
	private void actualizarVentana(ArrayList<ProductoIngrediente> productosIngredientes,boolean editable)
    {
		
    	if (!productosIngredientes.isEmpty())
    	{	
    		
		    //Para hacer No editable la tabla
			if (!editable)
		    {
			   
				Object[] encabezado= {"Codigo","Nombre Corto","Nombre Largo","Unid Medida","Costo","Cantidad"};
				
				Object[][] data= new Object[productosIngredientes.size()][encabezado.length];
				
				int i=0;
	
	            Iterator<ProductoIngrediente> iterador= productosIngredientes.iterator();
	
	            ProductoIngrediente productoIng;
	            
	            
	            while (iterador.hasNext())
	            {	
	            	productoIng= iterador.next();
	                data[i][0]= productoIng.getIngrediente().getCodigo();
	                data[i][1]= productoIng.getIngrediente().getNombreCorto();
	                data[i][2]= productoIng.getIngrediente().getNombreLargo();
	                data[i][3]= productoIng.getIngrediente().getUnidadMedida();
	                data[i][4]= productoIng.getIngrediente().getCosto();
	                data[i][5]= productoIng.getCantidad();
	                ++i;
	            }
		        modeloTabla= new ModeloTablaEstatico(data,encabezado);
		        interfazGrafica.asignarDatosTabla(modeloTabla);
		    }
			else //Para hacer editable la tabla
			{
	            String[] encabezado= {"","Codigo","Nombre Corto","Nombre Largo","Unid Medida","Costo","Cantidad"};
				
				Object[][] data= new Object[productosIngredientes.size()][encabezado.length];
				javax.swing.JTextField txtF= new javax.swing.JTextField();
				txtF.addKeyListener(new EscuchadorInterno());
				
				Iterator<ProductoIngrediente> iterador= productosIngredientes.iterator();
	
	            ProductoIngrediente productoIng;
	            
	            int i=0;
	            
	            while (iterador.hasNext())
	            {	
	            	productoIng= iterador.next();
	            	data[i][0]= new Boolean(false);
	                data[i][1]= productoIng.getIngrediente().getCodigo();
	                data[i][2]= productoIng.getIngrediente().getNombreCorto();
	                data[i][3]= productoIng.getIngrediente().getNombreLargo();
	                data[i][4]= productoIng.getIngrediente().getUnidadMedida();
	                data[i][5]= productoIng.getIngrediente().getCosto();
	                data[i][6]= "0.0";
	                ++i;
	            }
				
				
				
				modeloTabla= new ModeloTablaModificable(data,encabezado);
				interfazGrafica.asignarDatosTabla(modeloTabla);
				 
		      	TableColumn marcaVerificacion= interfazGrafica.getTableColumnModel().getColumn(0);
				TableColumn cantidad= interfazGrafica.getTableColumnModel().getColumn(6);
					
				cantidad.setCellEditor(new DefaultCellEditor(txtF));
				marcaVerificacion.setPreferredWidth(5);
				
			}
    	} 
		
    }
    
    
    private void actualizarVentana(Producto producto)
    {
    	try
    	{
		    if (producto!=null)
		    {  		
		    		interfazGrafica.actualizarInfo(producto.getCodigo(), producto.getNombreCorto(), 
		    				               producto.getNombreLargo(), producto.getPorcGanancia());
		    		interfazGrafica.asignarPrecioTotal(producto.getPrecio());
		    		if (producto.getCategoria()!=null)
		    		    interfazGrafica.asignarCategoria(producto.getCategoria().getCodCategoria());
		    }
		    else
		    {
		    	interfazGrafica.actualizarInfo("", "", "", 0.0f);
		    	interfazGrafica.asignarCategoria("");
		    	interfazGrafica.asignarPrecioTotal(0.0);
		    }
	    	
    	}
    	catch(Exception e)
    	{
    		Mensaje.mostrarError("Error Actualizando Ventana!!!");
    	}
    	
    }
    
    private void actualizarTotal()
    {
    	if (modeloTabla instanceof ModeloTablaModificable)
    	{
    		double total= 0.0; 
	    	try
			{
	    		
	    		for (int i=0; i < modeloTabla.getRowCount(); ++i)
				{
					if ((Boolean) modeloTabla.getValueAt(i, 0))
					{	
						double costo= Double.parseDouble(modeloTabla.getValueAt(i, 5).toString());  
						double cantidad=   Double.parseDouble(modeloTabla.getValueAt(i, 6).toString());
				        double porcGanancia= interfazGrafica.getPorcGanancia();
						
				        total += Math.floor(costo * cantidad);
				        total += ((porcGanancia * total)/100);
					}   
			        
				}	
	    		
	          
			}
			catch(NumberFormatException e){
			    total=0.0;
			}
			
			 
	        interfazGrafica.asignarPrecioTotal(total);
			
    	}
    }
	
	
	@Override
	protected Producto getObjecto() 
	{
		Producto producto= null;
		
		try
		{
		  if (isGuardando())
		  {
			producto= new Producto(interfazGrafica.getCodProducto(),
		             categoriaDao.getCategoria(interfazGrafica.getCategoria()),
		             interfazGrafica.getNombreCorto(), interfazGrafica.getNombreLargo(),interfazGrafica.getPorcGanancia());
			
			if (modeloTabla instanceof ModeloTablaModificable)
			{
				  
				  Ingrediente ingrediente;
				  
				  for (int i=0; i < modeloTabla.getRowCount(); ++i)
	              {
	                   if ((Boolean)modeloTabla.getValueAt(i,0))
	                   {
	                	   
	                	  interfazGrafica.asignarValoresEdicionTabla(i, 6); 
	                	   
	                      ingrediente= ingredienteDao.getIngrediente((String)modeloTabla.getValueAt(i, 1));  	   
	      
	                      double cantidad= 0.0;
	                      
	                      
	                      cantidad = Double.parseDouble((String)modeloTabla.getValueAt(i, 6));
	                      producto.agregarProductoIngrediente(new ProductoIngrediente(ingrediente,cantidad));
	                     
	                   }
	              }
			}
		  }
		  else
		  {
			   producto= new Producto(interfazGrafica.getCodProducto(),categoriaDao.getCategoria(interfazGrafica.getCategoria()),interfazGrafica.getNombreCorto(),interfazGrafica.getNombreLargo(),interfazGrafica.getPorcGanancia());
			   List<ProductoIngrediente> lista= new ProductoIngredienteDao().getProductosIngredientes(producto);
			   producto.sustituirProductosIngredientes(lista);
		  }
		}
		catch(Exception e)
		{
			Mensaje.mostrarError("Error Creando Producto!!!");
			producto=null;
		}
		
		return producto;
	}


	@Override
	protected boolean isValido(Object objeto) {
		boolean valido=false;
		
		if (objeto!=null && (objeto instanceof Producto))
		{
			Producto producto= (Producto) objeto;
			valido= producto.validar();
		}
		
		return valido;
	}


	@Override
	protected boolean isExiste(Object objeto) throws Exception 
	{
		boolean existe=false;
		
		if (objeto instanceof Producto)
		{
			Producto producto= (Producto) objeto;
			existe= productoDao.consultarProducto(producto);
		}
		
		return existe;
	}


	@Override
	protected boolean isEliminado(Object objeto) throws Exception 
	{
		boolean eliminado= false;
		
		if (objeto instanceof Producto)
		{
			Producto producto= (Producto) objeto;
			eliminado= productoDao.isEliminado(producto);
		}
		
		return eliminado;
	}


	@Override
	protected boolean activarObjeto(Object objeto) throws Exception 
	{
		boolean activado=false;
		
		if (objeto instanceof Producto)
		{
			Producto producto= (Producto) objeto;
			activado= productoDao.activarProducto(producto);
		}
		
		return activado;
	}


	@Override
	protected boolean registrarObjeto(Object objeto) throws Exception
	{
		boolean registrar=false;
		
		if (objeto instanceof Producto)
		{
			Producto producto= (Producto) objeto;
			registrar= productoDao.registrarProducto(producto);
		}
		
		return registrar;
	}


	@Override
	protected boolean actualizarObjeto(Object objeto) throws Exception 
	{
		boolean actualizar=false;
		
		if (objeto instanceof Producto)
		{
			Producto producto= (Producto) objeto;
			actualizar= productoDao.actualizarProducto(producto);
		}
		
		return actualizar;
	}


	@Override
	protected boolean eliminarObjeto(Object objeto) throws Exception 
	{
		boolean eliminado= false;
		
		if (objeto instanceof Producto)
		{
			Producto producto= (Producto) objeto;
			eliminado= productoDao.eliminarProducto(producto);
		}
		
		return eliminado;
	}


	@Override
	protected boolean isDependiente(Object objeto) throws Exception 
	{
		boolean dependiente=false;
		
		if (objeto instanceof Producto)
		{
			Producto producto= (Producto) objeto;
			dependiente= productoDao.isDependiente(producto);
		}
		
		return dependiente;
	}


	@Override
	protected void inicializarInfo() 
	{
		try
    	{
    		
    		if (!productos.isEmpty())	
    			productos.clear();
    		  
    		 productos.addAll(productoDao.consultarProductosActivos());
			 
			 actualizarVentana(null);
    		
    		 modeloTabla= new DefaultTableModel();
    		 interfazGrafica.asignarDatosTabla(modeloTabla);
    		
    		interfazGrafica.deshabilitarBotonActualizar("Guardar");
    		interfazGrafica.deshabilitarBotonActualizar("Modificar");
    		interfazGrafica.deshabilitarBotonActualizar("Eliminar");
    		interfazGrafica.deshabilitarBotonActualizar("Cancelar");
    		 
    		
    	}
    	catch(Exception e)
    	{
    		Mensaje.mostrarError(e.getMessage());
    		
			controladorPrincipal.visualizarVentanaPrincipal();
			interfazGrafica.descargarMemoria();
    	}
		
		
	}


	@Override
	public void windowClosing(WindowEvent arg0) 
	{
		interfazGrafica.descargarMemoria();
		controladorPrincipal.visualizarVentanaPrincipal();	
	}

	@Override
	public void windowOpened(WindowEvent arg0) {
		inicializarInfo();
		
	}

	@Override
	public void actionPerformed(ActionEvent e) 
	{
		if (e.getSource() instanceof javax.swing.JButton)
		{
			if (e.getActionCommand().equalsIgnoreCase("BuscarCategoria"))
			{
				new ControladorBuscarCategoria(this);
			}
			else if (e.getActionCommand().equalsIgnoreCase("Guardar"))
				guardar();
			else if(e.getActionCommand().equalsIgnoreCase("Modificar"))
				modificar();
			else if(e.getActionCommand().equalsIgnoreCase("Eliminar"))
				eliminar();
			else if (e.getActionCommand().equalsIgnoreCase("Cancelar"))
			{
				inicializarInfo();
			}		
		    else if (e.getActionCommand().equalsIgnoreCase("Salir"))
			{
		    	controladorPrincipal.visualizarVentanaPrincipal();
				interfazGrafica.descargarMemoria();
			}
			
		
		}		
		
	}


	@Override
	public void asignarElementoBuscado(String categoria) 
	{
		interfazGrafica.asignarCategoria(categoria);
		
	}


	@Override
	public VentanaIndependiente getVentana() {
		
		return interfazGrafica.getVentana();
	}
	
	
	private class ModeloTablaEstatico extends DefaultTableModel
	{
		

	    public ModeloTablaEstatico(Object[][] data, Object[] columnNames) 
	    {
		        super(data, columnNames);
	    }
  


		    @Override
		 public boolean isCellEditable(int row,int col)
         {
	          return false;
	
         }
		
	}
	
	private class ModeloTablaModificable extends AbstractTableModel
	{
		 
		   private  Object[][] info;
		   private  String[] titulo;

		   ModeloTablaModificable(Object[][] data,String[] titulos)
		   {
		         info= data;
		         titulo= titulos;
		         
		   }     
		   

		    public int getRowCount() {
		        return info.length;
		    }

		    public int getColumnCount() {
		       return titulo.length;
		    }

		    public Object getValueAt(int rowIndex, int columnIndex) {
		        return info[rowIndex][columnIndex];
		    }

		    public Class<? extends Object> getColumnClass(int c) {
		            return info[0][c].getClass();
		        }

		    public String getColumnName(int col) {
		            return titulo[col];
		        }


		    public boolean isCellEditable(int row,int col)
		    {
		        boolean editable= false;
		        if (col==0  || col==6)
		            editable= true;
		        return editable;
		    }

		    public void setValueAt(Object value, int row, int col)
		    {
		    	if (col==6)
		    	{
		    		actualizarTotal();
		    	}
		    	info[row][col]= value;
		        fireTableCellUpdated(row, col);
		    }
		
	}
	
	private class EscuchadorInterno implements KeyListener
	{

		@Override
		public void keyPressed(KeyEvent evt) {
			
			
		}

		@Override
		public void keyReleased(KeyEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void keyTyped(KeyEvent evt) {
			if (!(Character.isDigit(evt.getKeyChar()) || '.'==evt.getKeyChar()))		
	               evt.setKeyChar(Character.MIN_VALUE);
			
		}
		
	}


	@Override
	public void focusLost(FocusEvent evt) 
	{
		if (evt.getSource() instanceof javax.swing.JTextField)
		{
			
					
				Producto producto= new Producto(interfazGrafica.getCodProducto(),null,"","",0.0f);
				
					
				try
				{
				  
				  /*Actualiza el ArrayList con la base de datos*/
				  if (!productos.containsAll(productoDao.consultarProductosActivos()))
				  {
					  if (!productos.isEmpty())	
							productos.clear();
						  
					  productos.addAll(productoDao.consultarProductosActivos());
                     
				  } 
				 /********************************************/
				 	
				  if (productos.contains(producto))
				  {
					 				 
					 ArrayList<ProductoIngrediente> listaP= new ArrayList<ProductoIngrediente>();
					 Iterator <ProductoIngrediente> it= productos.get(productos.indexOf(producto)).getIterador();
					 
					 while (it.hasNext())
						 listaP.add(it.next());
					
					
					 
					 actualizarVentana(productos.get(productos.indexOf(producto)));
					 actualizarVentana(listaP,false);
					 interfazGrafica.asignarPrecioTotal(productos.get(productos.indexOf(producto)).getPrecio());
					 
					 interfazGrafica.deshabilitarBotonActualizar("Guardar");
					 interfazGrafica.habilitarBotonActualizar("Eliminar");
					 interfazGrafica.deshabilitarBotonActualizar("Modificar");
					 interfazGrafica.deshabilitarBotonActualizar("Cancelar");
					 
					 guardando=false;
					 
				  }
				  else
				  {
					 ArrayList<ProductoIngrediente> listaP= new ArrayList<ProductoIngrediente>();
					 List<Ingrediente> listaI= ingredienteDao.consultarIngredientesActivos();
					 
					 for (Ingrediente ing:listaI)
					 {
					    listaP.add(new ProductoIngrediente(ing,0.0)); 	 
					 }	
					 
					 actualizarVentana(producto);
					 actualizarVentana(listaP,true);
					 
					 interfazGrafica.limpiarTextos();
					 interfazGrafica.habilitarBotonActualizar("Guardar");
					 interfazGrafica.habilitarBotonActualizar("Cancelar");
					 interfazGrafica.deshabilitarBotonActualizar("Modificar");
					 interfazGrafica.deshabilitarBotonActualizar("Eliminar");
					 
					 guardando= true;
				  }
				  
				  
				}
				catch(Exception e)
				{
					Mensaje.mostrarError(e.getMessage());
				}
					
				
		}
		
		
	}

	

	@Override
	public void keyTyped(KeyEvent evt) 
	{
		if (evt.getSource() instanceof javax.swing.JTextField)
		{
			javax.swing.JTextField txt= (javax.swing.JTextField) evt.getSource();
			evt.setKeyChar(Character.toUpperCase(evt.getKeyChar()));
			if (txt.getName().equalsIgnoreCase("txtCodProducto"))
			{
				
				
				if (interfazGrafica.getCodProducto().length()==Producto.MAXCODIGO)
					evt.setKeyChar(Character.MIN_VALUE);
				
			}
			else if ((txt.getName().equalsIgnoreCase("txtNombreCorto")))
			{
				if (interfazGrafica.getNombreCorto().length()==Producto.MAXNOMBRECORTO)
					evt.setKeyChar(Character.MIN_VALUE);
				else
				{
					if (guardando)
					{
						interfazGrafica.habilitarBotonActualizar("Guardar");
						interfazGrafica.deshabilitarBotonActualizar("Modificar");
						interfazGrafica.deshabilitarBotonActualizar("Eliminar");
					}
				    else
					{
				    	interfazGrafica.deshabilitarBotonActualizar("Guardar");
				    	interfazGrafica.habilitarBotonActualizar("Modificar");
				    	interfazGrafica.deshabilitarBotonActualizar("Eliminar");
					}
					interfazGrafica.habilitarBotonActualizar("Cancelar");
				}
			}
			else if (txt.getName().equalsIgnoreCase("txtNombreLargo"))
			{
				if (interfazGrafica.getNombreLargo().length()==Producto.MAXNOMBRELARGO)
					evt.setKeyChar(Character.MIN_VALUE);
				else
				{
					if (guardando)
					{
						interfazGrafica.habilitarBotonActualizar("Guardar");
						interfazGrafica.deshabilitarBotonActualizar("Modificar");
						interfazGrafica.deshabilitarBotonActualizar("Eliminar");
					}
				    else
					{
				    	interfazGrafica.deshabilitarBotonActualizar("Guardar");
				    	interfazGrafica.habilitarBotonActualizar("Modificar");
				    	interfazGrafica.deshabilitarBotonActualizar("Eliminar");
					}
					interfazGrafica.habilitarBotonActualizar("Cancelar");
				}
			}
			else if (txt.getName().equalsIgnoreCase("txtPorcGanancia"))
			{		
				if ((char)KeyEvent.VK_BACK_SPACE!= evt.getKeyChar() && !Character.isDigit(evt.getKeyChar()) && '.'!=evt.getKeyChar())
			         evt.setKeyChar(Character.MIN_VALUE);
				else
				{
					actualizarTotal();
					if (guardando)
					{
						interfazGrafica.habilitarBotonActualizar("Guardar");
						interfazGrafica.deshabilitarBotonActualizar("Modificar");
						interfazGrafica.deshabilitarBotonActualizar("Eliminar");
					}
				    else
					{
				    	interfazGrafica.deshabilitarBotonActualizar("Guardar");
				    	interfazGrafica.habilitarBotonActualizar("Modificar");
				    	interfazGrafica.deshabilitarBotonActualizar("Eliminar");
					}
					interfazGrafica.habilitarBotonActualizar("Cancelar");
				}
				
			}
			
			
			
		}
		
		
	}
	
	@Override
	public void propertyChange(PropertyChangeEvent evt) 
	{
		
			if (guardando)
			{
				interfazGrafica.habilitarBotonActualizar("Guardar");
				interfazGrafica.deshabilitarBotonActualizar("Modificar");
				interfazGrafica.deshabilitarBotonActualizar("Eliminar");
			}
		    else
			{
		    	interfazGrafica.deshabilitarBotonActualizar("Guardar");
		    	interfazGrafica.habilitarBotonActualizar("Modificar");
		    	interfazGrafica.deshabilitarBotonActualizar("Eliminar");
			}
			interfazGrafica.habilitarBotonActualizar("Cancelar");
		
		
	}
	
	@Override
	public void keyPressed(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void windowDeactivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowDeiconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowIconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	

	@Override
	public void windowActivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowClosed(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	

	@Override
	public void focusGained(FocusEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	

	
}
